package com.suemi.missile.plugin;

import com.suemi.missile.common.mql.SearchDao;
import com.suemi.missile.common.mql.exception.MqlFeatureNotSupportedException;
import com.suemi.missile.common.mql.exception.MqlParseException;
import com.suemi.missile.common.mql.query.QueryAction;
import com.suemi.missile.plugin.executors.RestExecutor;
import com.suemi.missile.plugin.executors.RestExecutorFactory;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RestMqlAction extends BaseRestHandler {

  @Inject
  protected RestMqlAction(Settings settings, RestController controller) {
    super(settings);
    controller.registerHandler(RestRequest.Method.POST, "/missile/_mql", this);
    controller.registerHandler(RestRequest.Method.GET, "/missile/_mql", this);
  }

  @Override
  protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {

    String mql = request.param("mql");
    if(mql == null) mql = request.content().utf8ToString();
    if(!mql.endsWith(";")) mql = mql + ";";

    try {
      SearchDao dao = new SearchDao(client);
      QueryAction action = dao.explain(mql);

      Map<String, String> params = request.params();
      RestExecutor restExecutor = RestExecutorFactory.createExecutor(params.get("format"));
      final QueryAction finalQueryAction = action;
      //doing this hack because elasticsearch throws exception for un-consumed props
      Map<String,String> additionalParams = new HashMap<>();
      List<String> additionalParamsNames = Arrays.asList("_type","_id","_score");
      for(String paramName : additionalParamsNames) {
        additionalParams.put(paramName, request.param(paramName));
      }
      return channel -> restExecutor.execute(client,additionalParams, finalQueryAction,channel);
    } catch (MqlFeatureNotSupportedException | MqlParseException e) {
      e.printStackTrace();
    }

    return null;
  }
}
